package org.visionlibrary.image.filters.histogram;

import javax.media.jai.TiledImage;

import org.visionlibrary.image.acquisition.ImageFactory;
import org.visionlibrary.image.model.AbstractFilter;
import org.visionlibrary.image.model.FilterTools;


//TODO Poprawic algorytm nie uwzglednia wartosci najmniejszej
public class HistogramReleysEquation extends AbstractFilter {
	//private int newMin;
	private int newMax;
	private float alfa = 3;

	public HistogramReleysEquation(int newMin, int newMax, float alfa) {
		//this.newMin = newMin;
		this.newMax = newMax;
		this.alfa = alfa;
	}

	public TiledImage applyFilter(TiledImage src, TiledImage dest) {
		if (null == src)
			throw new NullPointerException("Source image is null.");

		if (null == dest)
			dest = (new ImageFactory()).createCompatibleImage(src);
		
		int[] lut = new int[256];
		for (int channel = 0; channel < src.getNumBands(); channel++) {
			int[] histogram = FilterTools.getHistogram(src, channel);

			// accumulative histogram;
			for (int i = 1; i < histogram.length; i++)
				histogram[i] += histogram[i - 1];

			// create lut;
			double subResult = 2 * alfa * alfa;
			int numPixels = src.getHeight() * src.getWidth();
			float oneByNumPixels = 1.0f / numPixels;
			for (int f = 0; f < 256; f++)
				lut[f] = (int) (newMax + Math.sqrt(subResult
						* Math.log(oneByNumPixels * histogram[f])));

			// use lut to create new pixel values;
			for (int y = 0; y < src.getHeight(); y++)
				for (int x = 0; x < src.getWidth(); x++)
					dest.setSample(x, y, channel, lut[src.getSample(x, y,
							channel)]);
		}

		return dest;
	}
}
